package com.hy.frame.ui;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.SparseArray;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.DrawableRes;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.appcompat.widget.Toolbar;

import com.hy.frame.R;
import com.hy.frame.util.ResUtil;

/**
 * title Toolbar生成器
 * author HeYan
 * time 2021/2/9 9:57
 * desc 无
 */
public class ToolbarUI implements View.OnClickListener {

    protected Context mContext;
    protected Runnable mLeftCallback;
    protected Runnable mRightCallback;
    protected View.OnClickListener mListener;
    protected ViewGroup mToolbar; //标题栏
    protected ViewGroup mHeader; //标题栏容器
    protected View vBackground;
    protected int mStatusBarHeight;//状态栏高度
    protected int mToolbarHeight;//头部高度(不包含状态栏)
    protected int mNotchHeight;//刘海栏高度
    protected boolean isTranslucentStatus;//是否开启透明状态栏功能
    protected long mLastTime;
    protected boolean isCheckFastClick;//是否检测快速点击
    protected CharSequence mTitle;//标题
    protected Drawable mLeftIcon;//左图标
    protected Drawable mRightIcon;//左图标

    public ToolbarUI(@NonNull Context context) {
        this(context, null);
    }

    public ToolbarUI(@NonNull Context context, @Nullable Runnable leftCallback) {
        this(context, leftCallback, null);
    }

    /**
     * @param leftCallback  头-左边图标点击
     * @param rightCallback 头-右边图标点击
     */
    public ToolbarUI(@NonNull Context context, @Nullable Runnable leftCallback, @Nullable Runnable rightCallback) {
        this.mContext = context;
        this.mLeftCallback = leftCallback;
        this.mRightCallback = rightCallback;
    }

    @NonNull
    protected Context getContext() {
        return this.mContext;
    }

    @NonNull
    protected Resources getResources() {
        return getContext().getResources();
    }

    /**
     * 设置状态栏高度，不设置取默认值
     */
    public ToolbarUI setStatusBarHeight(int height) {
        this.mStatusBarHeight = height;
        return this;
    }

    /**
     * 是否开启状态栏透明功能，开启后Toolbar会自动添加paddingTop
     */
    public ToolbarUI setTranslucentStatus(boolean enable) {
        this.isTranslucentStatus = enable;
        return this;
    }

    /**
     * 设置标题栏高度，不设置取默认值
     */
    public ToolbarUI setToolbarHeight(int height) {
        this.mToolbarHeight = height;
        return this;
    }

    /**
     * 设置刘海栏高度，不设置取默认值
     */
    public ToolbarUI setNotchHeight(int height) {
        this.mNotchHeight = height;
        return this;
    }

    /**
     * 设置Toolbar，不设置取默认值
     */
    public ToolbarUI setToolbar(@Nullable Toolbar toolbar) {
        this.mToolbar = toolbar;
        return this;
    }

    protected int getLayoutId() {
        return R.layout.in_header;
    }

    /**
     * 设置标题
     */
    public ToolbarUI setTitle(@StringRes int strId) {
        return setTitle(getResources().getString(strId));
    }

    /**
     * 设置标题
     */
    public ToolbarUI setTitle(@Nullable CharSequence title) {
        this.mTitle = title;
        if (this.mHeader == null) return this;
        View v = findViewById(R.id.kf_title);
        if (v == null) {
            if (title == null) return this;
            View.inflate(getContext(), R.layout.in_head_title, this.mHeader);
            v = findViewById(R.id.kf_title);
        }
        if (v instanceof TextView) {
            ((TextView) v).setText(title);
        }
        return this;
    }

    /**
     * 设置左图标
     */
    public ToolbarUI setLeftIcon(@DrawableRes int icon) {
        return setLeftIcon(icon == 0 ? null : AppCompatResources.getDrawable(getContext(), icon));
    }

    /**
     * 设置左图标
     */
    public ToolbarUI setLeftIcon(@Nullable Drawable icon) {
        this.mLeftIcon = icon;
        initLeftIcon(icon, null);
        return this;
    }

    /**
     * 设置左文本按钮
     */
    public void setLeftText(@Nullable CharSequence text) {
        this.mLeftIcon = null;
        initLeftIcon(null, text);
    }

    @SuppressLint("RtlHardcoded")
    private void initLeftIcon(@Nullable Drawable icon, @Nullable CharSequence text) {
        if (this.mHeader == null) return;
        View v = findViewById(R.id.kf_left);
        if (v == null) {
            if (icon == null && text == null) return;
            boolean image = (text == null);
            if (image) {
                View.inflate(getContext(), R.layout.in_head_left, this.mHeader);
            } else {
                View.inflate(getContext(), R.layout.in_head_tleft, this.mHeader);
            }
            v = findViewById(R.id.kf_left);
            //this.cToolbar.addView(v, generateHeadActionLayoutParams(image, Gravity.LEFT));
        }
        if (v instanceof ImageView) {
            ((ImageView) v).setImageDrawable(icon);
            v.setOnClickListener(this);
        } else if (v instanceof TextView) {
            ((TextView) v).setText(text);
            v.setOnClickListener(this);
        }
    }

    /**
     * 设置右图标
     */
    public ToolbarUI setRightIcon(@DrawableRes int icon) {
        return setRightIcon(icon == 0 ? null : AppCompatResources.getDrawable(getContext(), icon));
    }

    /**
     * 设置右图标
     */
    public ToolbarUI setRightIcon(@Nullable Drawable icon) {
        this.mRightIcon = icon;
        initRightIcon(icon, null);
        return this;
    }

    /**
     * 设置右文本按钮
     */
    public void setRightText(@Nullable CharSequence text) {
        this.mRightIcon = null;
        initRightIcon(null, text);
    }

    @SuppressLint("RtlHardcoded")
    private void initRightIcon(@Nullable Drawable icon, @Nullable CharSequence text) {
        if (this.mHeader == null) return;
        View v = findViewById(R.id.kf_right);
        if (v == null) {
            if (icon == null && text == null) return;
            boolean image = (text == null);
            if (image) {
                View.inflate(getContext(), R.layout.in_head_right, mHeader);
            } else {
                View.inflate(getContext(), R.layout.in_head_tright, mHeader);
            }
            v = findViewById(R.id.kf_right);
            //this.cToolbar.addView(v, generateHeadActionLayoutParams(image, Gravity.RIGHT));
        }
        if (v instanceof ImageView) {
            ((ImageView) v).setImageDrawable(icon);
            v.setOnClickListener(this);
        } else if (v instanceof TextView) {
            ((TextView) v).setText(text);
            v.setOnClickListener(this);
        }
    }

    /**
     * 添加右图标
     */
    public void addRightIcon(@DrawableRes int icon, @IdRes int id) {
        addRightIcon(icon == 0 ? null : AppCompatResources.getDrawable(getContext(), icon), id);
    }

    private SparseArray<View> mRightViews;

    public void addRightIcon(@Nullable Drawable icon, @IdRes int id) {
        if (this.mHeader == null) return;
        if (icon == null || id == View.NO_ID) return;
        View first = findViewById(R.id.kf_right);
        if (first != null && !(first instanceof ImageView)) {//如果右侧第一个图标不是图片则拦截
            return;
        }
        int rightMargin = 0;
        if (first != null) {
            rightMargin += getToolbarHeight();
        }
        if (mRightViews == null) {
            mRightViews = new SparseArray<>();
        } else if (mRightViews.get(id) != null) {
            return;
        } else {
            rightMargin += mRightViews.size() * getToolbarHeight();
        }
        View v = View.inflate(getContext(), R.layout.in_head_right, null);
        v.setId(id);
        ((ImageView) v).setImageDrawable(icon);
        ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(getToolbarHeight(), getToolbarHeight());
        if (this.mHeader instanceof FrameLayout) {
            lp = new FrameLayout.LayoutParams(lp);
            ((FrameLayout.LayoutParams) lp).gravity = Gravity.RIGHT;
        }
        lp.rightMargin = rightMargin;
        this.mHeader.addView(v, lp);
        resetTitleMargin();
    }

    public void setListener(@Nullable View.OnClickListener listener) {
        this.mListener = listener;
    }

    /**
     * 重设title Margin
     */
    private void resetTitleMargin() {
        View v = findViewById(R.id.kf_title);
        if (v == null) return;
        int leftSize = 0;
        int rightSize = 0;
        View left = findViewById(R.id.kf_left);
        if (left != null) {
            leftSize++;
        }
        View right = findViewById(R.id.kf_right);
        if (right != null) {
            rightSize++;
        }
        if (mRightViews != null) {
            rightSize += mRightViews.size();
        }
        int size = Math.max(rightSize, leftSize);
        if (size == 0) return;
        int margin = size * getToolbarHeight();
        ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
        lp.leftMargin = margin;
        lp.rightMargin = margin;
        v.setLayoutParams(lp);
    }

    /**
     * 是否检测快速点击
     */
    public ToolbarUI setCheckFastClick(boolean check) {
        this.isCheckFastClick = check;
        return this;
    }

    /**
     * 是否是快速点击
     */
    protected boolean isFastClick() {
        long time = System.currentTimeMillis();
        if (time - this.mLastTime < 500L) return true;
        this.mLastTime = time;
        return false;
    }

    /**
     * 初始化Toolbar
     */
    protected void initToolbar(@Nullable ActionBar actionBar, @Nullable ViewGroup container, @Nullable ViewGroup.LayoutParams params) {
        if (actionBar == null && container == null) {
            return;
        }
        if (actionBar != null) {
            actionBar.setTitle(R.string.empty);
            if (actionBar.getCustomView() instanceof ViewGroup) {
                mHeader = (ViewGroup) actionBar.getCustomView();
            } else {
                mHeader = new FrameLayout(getContext());
                mHeader.setId(R.id.kf_header);
                mHeader.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getToolbarHeight()));
                //mHeader.setFitsSystemWindows(false);
                //actionBar.setDisplayShowCustomEnabled(true);
                //actionBar.setDisplayShowHomeEnabled(false);
                //actionBar.setDisplayShowTitleEnabled(false);
                //actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
                //actionBar.setCustomView(this.mToolbar, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
                actionBar.setCustomView(mHeader);
                //((Toolbar)this.mToolbar.getParent()).setContentInsetsAbsolute(0, 0);
            }
            //actionBar.setBackgroundDrawable(getToolbarBackground());
            //actionBar.setSplitBackgroundDrawable(getToolbarBackground());
            //actionBar.setStackedBackgroundDrawable(getToolbarBackground());
            //actionBar.setElevation(0);
            mToolbar = (ViewGroup) mHeader.getParent();
        } else {
            Toolbar toolbar = container.findViewById(R.id.kf_toolbar);
            if (toolbar != null) {
                this.mToolbar = toolbar;
                this.mHeader = toolbar.findViewById(R.id.kf_header);
            } else {
                this.mToolbar = new Toolbar(getContext());
                this.mToolbar.setId(R.id.kf_toolbar);
                if (params == null) {
                    params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                }
                this.mToolbar.setLayoutParams(params);
                this.mToolbar.setBackground(getToolbarBackground());
                //如果container是LinearLayout需要移到最前面
                if (container instanceof LinearLayout) {
                    container.addView(this.mToolbar, 0);
                } else {
                    container.addView(mToolbar);
                }
            }
            if (this.mHeader == null) {
                this.mHeader = new FrameLayout(getContext());
                this.mHeader.setId(R.id.kf_header);
                this.mHeader.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getToolbarHeight()));
                this.mToolbar.addView(mHeader);
            }
            if (this.mToolbar instanceof Toolbar)
                ((Toolbar) this.mToolbar).setTitle(R.string.empty);
        }
        setTitle(mTitle);
        setLeftIcon(mLeftIcon);
        setRightIcon(mRightIcon);
        //沉侵式状态栏，防止标题栏和状态栏重叠逻辑
        if (!isTranslucentStatus || mToolbar == null) return;
        if (getStatusBarHeight() > 0 && getToolbarHeight() > 0) {
            int statusHeight = getStatusBarHeight();
            if (mNotchHeight > 0 && mNotchHeight > getStatusBarHeight())
                statusHeight = mNotchHeight;
            if (actionBar != null) {
                int findCount = 5;
                View v = mToolbar;
                View content = null;
                while (findCount > 0) {
                    findCount--;
                    if (v.getParent() != null) {
                        v = (View) v.getParent();
                        content = v.findViewById(android.R.id.content);
                        if (content != null) {
                            break;
                        }
                    }
                }
                if (content != null) {
                    View vBackground = new View(getContext());
                    ViewGroup group = (ViewGroup) content;
                    vBackground.setBackground(getToolbarBackground());
                    group.addView(vBackground, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getToolbarHeight() + statusHeight));
                    if (group.getChildCount() > 1) {
                        View layout = group.getChildAt(1);
                        if (layout.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
                            ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) layout.getLayoutParams();
                            lp.topMargin = getToolbarHeight() + statusHeight;
                            layout.setLayoutParams(lp);
                        }
                    }
                }
            } else {
                mToolbar.setPadding(mToolbar.getPaddingLeft(), statusHeight, mToolbar.getPaddingRight(), mToolbar.getPaddingBottom());
                ViewGroup.LayoutParams lp = mToolbar.getLayoutParams();
                if (lp == null) {
                    lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getToolbarHeight() + statusHeight);
                } else {
                    lp.height = getToolbarHeight() + statusHeight;
                }
                mToolbar.setLayoutParams(lp);
            }
        }
    }

    /**
     * 获取 控件
     *
     * @param id 布局中某个组件的id
     */
    public <V extends View> V findViewById(int id) {
        if (this.mHeader == null) return null;
        return mHeader.findViewById(id);
    }


    /**
     * 获取 控件
     *
     * @param id     布局中某个组件的id
     * @param parent parent
     */
    public <V extends View> V findViewById(int id, View parent) {
        if (parent != null)
            return parent.findViewById(id);
        return findViewById(id);
    }

    private int getStatusBarHeight() {
        if (mStatusBarHeight == 0) {
            mStatusBarHeight = ResUtil.getStatusBarHeight(getContext());
        }
        return mStatusBarHeight;
    }

    private int getToolbarHeight() {
        if (mToolbarHeight == 0) {
            int[] attr = new int[]{R.attr.appToolbarHeight};
            TypedArray array = getContext().getTheme().obtainStyledAttributes(attr);
            mToolbarHeight = array.getDimensionPixelSize(0, getResources().getDimensionPixelSize(R.dimen.header_height));
            array.recycle();
        }
        return mToolbarHeight;
    }

    private Drawable mToolbarBackground;

    private Drawable getToolbarBackground() {
        if (mToolbarBackground == null) {
            int[] attr = new int[]{R.attr.appToolbarBackground};
            TypedArray array = getContext().getTheme().obtainStyledAttributes(attr);
            Drawable drawable = null;
            if (array.getIndexCount() > 0) {
                drawable = array.getDrawable(0);
            }
            array.recycle();
            if (drawable == null)
                drawable = new ColorDrawable(getThemeColor());
            mToolbarBackground = drawable;
        }
        return mToolbarBackground;
    }

    private int mThemeColor;

    private int getThemeColor() {
        if (mThemeColor == 0) {
            int[] attr = new int[]{R.attr.appThemeColor};
            TypedArray array = getContext().getTheme().obtainStyledAttributes(attr);
            mThemeColor = array.getColor(0, Color.WHITE);
            array.recycle();
        }
        return mThemeColor;
    }

    @Override
    public void onClick(View v) {
        if (isCheckFastClick && isFastClick()) return;
        int id = v.getId();
        if (id == R.id.kf_left && mLeftCallback != null) {
            mLeftCallback.run();
        } else if (id == R.id.kf_right && mRightCallback != null) {
            mRightCallback.run();
        } else if (this.mListener != null) {
            this.mListener.onClick(v);
        }
    }

    public ToolbarUI build(@Nullable ViewGroup container) {
        return build(null, container, null);
    }

    public ToolbarUI build(@Nullable ViewGroup container, @Nullable ViewGroup.LayoutParams params) {
        return build(null, container, params);
    }

    public ToolbarUI build(@Nullable ActionBar actionBar) {
        return build(actionBar, null, null);
    }

    public ToolbarUI build(@Nullable ActionBar actionBar, @Nullable ViewGroup container, @Nullable ViewGroup.LayoutParams params) {
        initToolbar(actionBar, container, params);
        return this;
    }
}

